#include "AnimationVec3Curve.h"
#include "Common.h"
#include <glm/vec3.hpp>

namespace DYGraphics
{
	bool IsEqual(glm::vec3 vec1, glm::vec3 vec2)
	{
		return abs(vec1.x - vec2.x) < 0.0001f && abs(vec1.y - vec2.y) < 0.0001f && abs(vec1.z - vec2.z) < 0.0001f;
	}

	glm::vec3 Lerp(glm::vec3 vec1, glm::vec3 vec2, float t)
	{
		return vec1 + (vec2 - vec1) * t;
	}

	void AnimationVec3Curve::AddKey(float pTime, glm::vec3 pValue)
	{
		AnimationVec3Key key = { pTime, pValue };
		if (mKeys.size() <= 1)
		{
			mKeys.push_back(key);
		}
		else
		{
			int endIdx = mKeys.size() - 1;
			if (IsEqual(pValue, mKeys[endIdx].value))
			{
				mKeys[endIdx].mTime = pTime;
			}
			else 
			{
				mKeys.push_back(key);
			}
		}
	}

	glm::vec3 AnimationVec3Curve::Evaluate(float mTime)
	{
		if (mKeys.empty())
		{
			Print("AnimationVec3Curve::Evaluate has no key \n");
			return glm::vec3();
		}

		int size = mKeys.size();
		AnimationVec3Key startKey = mKeys[0];
		AnimationVec3Key stopKey = mKeys[size - 1];

		if (mTime < startKey.mTime || mTime > stopKey.mTime)
		{
			Print("AnimationVec3Curve::Evaluate mTime is invalid\n");
			return glm::vec3();
		}

		if (mTime == startKey.mTime) return startKey.value;
		if (mTime == stopKey.mTime) return stopKey.value;

		AnimationVec3Key preKey = startKey;
		for (int i = 1; i < mKeys.size(); i++)
		{
			AnimationVec3Key key = mKeys[i];
			if (mTime == key.mTime) return key.value;

			if (mTime < key.mTime)
			{
				return Lerp(preKey.value, key.value, (mTime - preKey.mTime) / (key.mTime - preKey.mTime));
			}

			preKey = key;
		}

		Print("AnimationVec3Curve::Evaluate ???\n");
		return glm::vec3();
	}
}
